package com.boot2.core.dao.batch.insert;

import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author zhangweilin
 * @Description: 缓存于本地内存的批量提交方案
 * @date 2020/8/15
 */
@Component
public class BatchCommitDataWithMemory implements BatchCommitData {

    /**
     * 要批量提交的数据
     */
    private final Map<String, Queue<?>> taskQueueMap = new ConcurrentHashMap<>();

    @Override
    public <T> void init(String key) {
        synchronized (taskQueueMap) {
            Queue<?> queue = taskQueueMap.get(key);
            if (null == queue) {
                queue = new ConcurrentLinkedQueue<>();
                taskQueueMap.put(key, queue);
            }
        }
    }

    /**
     * 预提交
     *
     * @param key
     * @param t
     */
    @Override
    public <T> void preCommit(final String key, T t) {
        Queue<T> queue = getQueue(key);
        queue.offer(t);
    }

    private <T> Queue<T> getQueue(String key) {
        return (Queue<T>) taskQueueMap.get(key);
    }


    /**
     * 从队列取数据
     */
    @Override
    public <T> T poll(final String key) {
        Queue<T> queue = getQueue(key);
        T value = queue.poll();
        return value;
    }

    /**
     * 从队列取数据
     */
    @Override
    public <T> List<T> pollList(final String key, int size) {
        List<T> objList = new ArrayList<>();
        T o = null;
        Queue<T> queue = getQueue(key);
        while ((o = queue.poll()) != null) {
            --size;
            objList.add(o);
            if (size == 0) {
                break;
            }
        }
        return objList;
    }

    @Override
    public boolean isEmpty(String key) {
        Queue<T> queue = getQueue(key);
        boolean isEmpty = queue.isEmpty();
        return isEmpty;
    }

    @Override
    public Long size(String key) {
        Queue<T> queue = getQueue(key);
        Long size = Long.valueOf(queue.size());
        return size;
    }
}
